import { Table } from "antd";
import "./style.less";
import type { TableProps } from "antd";
import { nanoid } from "nanoid";

export interface FlexProps {
  type?: "container" | "item";
  flexCategory?: "flex" | "inline-flex" | "-webkit-flex";
  flexDirection?: "row" | "row-reverse" | "column" | "column-reverse";
  flexWrap?: "nowrap" | "wrap" | "wrap-reverse";
  flexFlow?:
    | "row nowrap"
    | "row wrap"
    | "row wrap-reverse"
    | "row-reverse nowrap"
    | "row-reverse wrap"
    | "row-reverse wrap-reverse"
    | "column nowrap"
    | "column wrap"
    | "column wrap-reverse"
    | "column-reverse nowrap"
    | "column-reverse wrap"
    | "column-reverse wrap-reverse";
  justifyContent?:
    | "flex-start"
    | "flex-end"
    | "center"
    | "space-between"
    | "space-around";
  alignItems?: "flex-start" | "flex-end" | "center" | "baseline" | "stretch";
  alignContent?:
    | "flex-start"
    | "flex-end"
    | "center"
    | "space-between"
    | "space-around"
    | "stretch";
  order?: number;
  flexGrow?: number;
  flexShrink?: number;
  flexBasis?: number | string;
  flex?: string;
  alignSelf?:
    | "auto"
    | "flex-start"
    | "flex-end"
    | "center"
    | "baseline"
    | "stretch";
}

interface DataType {
  key: string;
  api: string;
  property?: string;
  description?: string;
}

export const Flex = (props: FlexProps) => {
  const {
    type = "container",
    flexCategory = "flex",
    flexDirection = "row",
    flexWrap,
    flexFlow,
    justifyContent,
    alignItems,
    alignContent,
    order,
    flexGrow,
    flexShrink,
    flexBasis,
    flex,
    alignSelf,
  } = props;
  const flexCategoryEle = (
    <div className="box bg-primary">
      {flexCategory === "flex" && (
        <div className="flex flex-box">
          <div>块级元素</div>
          <div>块级元素</div>
          <div>块级元素</div>
        </div>
      )}
      {flexCategory === "inline-flex" && (
        <div className="inline-flex inline-flex-box">
          <span>内联元素</span>
          <span>内联元素</span>
          <span>内联元素</span>
        </div>
      )}
      {flexCategory === "-webkit-flex" && <div>Webkit内核浏览器</div>}
    </div>
  );

  const flexDirectionEle = (
    <div className="box bg-primary">
      <div className={`flex flex-box`} style={{ flexDirection }}>
        <div>元素1</div>
        <div>元素2</div>
        <div>元素3</div>
      </div>
    </div>
  );

  const flexWrapEle = (
    <div className="box bg-primary">
      <div className={`flex flex-box`} style={{ flexWrap }}>
        {Array.from({ length: 7 }).map((_, index) => (
          <div>元素{index}</div>
        ))}
      </div>
    </div>
  );

  const flexFlowEle = (
    <div className="box bg-primary">
      <div className="flex flex-box h-24" style={{ flexFlow }}>
        {Array.from({ length: 7 }).map((_, index) => (
          <div>元素{index}</div>
        ))}
      </div>
    </div>
  );

  const justifyContentEle = (
    <div className="box bg-primary">
      <div className="flex flex-box" style={{ justifyContent }}>
        {Array.from({ length: 3 }).map((_, index) => (
          <div>元素{index}</div>
        ))}
      </div>
    </div>
  );

  const alignItemsEle = (
    <div className="box bg-primary">
      <div className="flex flex-box h-16" style={{ alignItems }}>
        {Array.from({ length: 3 }).map((_, index) => (
          <div className="alignItem">元素{index}</div>
        ))}
      </div>
    </div>
  );

  const alignContentEle = (
    <div className="box bg-primary">
      <div className="flex flex-box flex-wrap h-36" style={{ alignContent }}>
        {Array.from({ length: 7 }).map((_, index) => (
          <div className="alignContent">元素{index}</div>
        ))}
      </div>
    </div>
  );

  const columns: TableProps<DataType>["columns"] = [
    {
      title: "api",
      dataIndex: "api",
      key: "api",
    },
    {
      title: "属性",
      dataIndex: "property",
      key: "property",
      render: (value: string) => {
        switch (value) {
          case "flex-category":
            return flexCategoryEle;
          case "flex-direction":
            return flexDirectionEle;
          case "flex-wrap":
            return flexWrapEle;
          case "flex-flow":
            return flexFlowEle;
          case "justify-content":
            return justifyContentEle;
          case "align-items":
            return alignItemsEle;
          case "align-content":
            return alignContentEle;
          default:
            break;
        }
      },
    },
    {
      title: "描述",
      dataIndex: "description",
      key: "description",
      render: (value: string) => {
        return <div dangerouslySetInnerHTML={{ __html: value }} />;
      },
    },
  ];

  const data: DataType[] = [
    {
      key: nanoid(),
      api: "弹性盒类别",
      property: "flex-category",
    },
    {
      key: nanoid(),
      api: "容器属性",
    },
    {
      key: nanoid(),
      api: "flex-direction",
      property: "flex-direction",
      description:
        "主轴方向row（默认值）：<br>主轴为水平方向，起点在左端。<br>row-reverse：主轴为水平方向，起点在右端。<br>column：主轴为垂直方向，起点在上沿。<br>column-reverse：主轴为垂直方向，起点在下沿。",
    },
    {
      key: nanoid(),
      api: "flex-wrap",
      property: "flex-wrap",
      description:
        "flex-wrap属性定义，如果一条轴线排不下，如何换行。<br>（1）nowrap（默认）：不换行。<br>（2）wrap：换行，第一行在上方。<br>（3）wrap-reverse：换行，第一行在下方。",
    },
    {
      key: nanoid(),
      api: "flex-flow",
      property: "flex-flow",
      description:
        "flex-flow属性是flex-direction属性和flex-wrap属性的简写形式，默认值为row nowrap",
    },
    {
      key: nanoid(),
      api: "justify-content",
      property: "justify-content",
      description:
        "justify-content属性定义了项目在主轴上的对齐方式。<br>flex-start（默认值）：左对齐<br>flex-end：右对齐<br>center： 居中<br>space-between：两端对齐，项目之间的间隔都相等。<br>space-around：每个项目两侧的间隔相等。所以，项目之间的间隔比项目与边框的间隔大一倍。",
    },
    {
      key: nanoid(),
      api: "align-items",
      property: "align-items",
      description:
        "align-items属性定义项目在交叉轴上如何对齐。<br>flex-start：交叉轴的起点对齐。<br>flex-end：交叉轴的终点对齐。<br>center：交叉轴的中点对齐。<br>baseline: 项目的第一行文字的基线对齐。<br>stretch（默认值）：如果项目未设置高度或设为auto，将占满整个容器的高度。",
    },
    {
      key: nanoid(),
      api: "align-content",
      property: "align-content",
      description:
        "align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线，该属性不起作用。<br>flex-start：与交叉轴的起点对齐。<br>flex-end：与交叉轴的终点对齐。<br>center：与交叉轴的中点对齐。<br>space-between：与交叉轴两端对齐，轴线之间的间隔平均分布。<br>space-around：每根轴线两侧的间隔都相等。所以，轴线之间的间隔比轴线与边框的间隔大一倍。<br>stretch（默认值）：轴线占满整个交叉轴。",
    },
  ];

  const orderEle = (
    <div id="order" className="box bg-primary">
      <div className="flex flex-box">
        <div style={{ order }}>order元素</div>
        <div className="order-3">元素3</div>
        <div className="order-4">元素4</div>
        <div className="order-5">元素5</div>
      </div>
    </div>
  );

  const flexGrowEle = (
    <div id="flex-grow" className="box bg-primary">
      <div className="flex flex-box">
        <div style={{ flexGrow }}>元素</div>
        <div className="flex-grow-[2]">元素3</div>
        <div className="flex-grow-[2]">元素4</div>
      </div>
    </div>
  );

  const flexShrinkEle = (
    <div id="flex-shrink" className="box bg-primary">
      <div className="flex flex-box">
        <div style={{ flexShrink }}>元素</div>
        <div className="flex-shrink-[2]">元素3</div>
        <div className="flex-shrink-[1]">元素4</div>
        <div className="flex-shrink-[1]">元素5</div>
      </div>
    </div>
  );
  const flexBasisEle = (
    <div id="flex-basis" className="box bg-primary">
      <div className="flex flex-box">
        <div style={{ flexBasis }}>元素</div>
        <div style={{ flex: "0 0 0" }}>元素3</div>
        <div style={{ flex: "0 0 0" }}>元素4</div>
      </div>
    </div>
  );
  const flexEle = (
    <div id="flex" className="box bg-primary">
      <div className="flex flex-box">
        <div style={{ flex }}>元素</div>
        <div style={{ flex }}>元素3</div>
        <div style={{ flex }}>元素4</div>
      </div>
    </div>
  );
  const alignSelfEle = (
    <div id="align-self" className="box bg-primary">
      <div className="flex flex-box h-24 items-start">
        <div style={{ alignSelf }} className="align-self">
          元素
        </div>
        <div className="flex-grow-0 align-self">元素3</div>
        <div className="flex-grow-0 align-self">元素4</div>
        <div className="flex-grow-0 align-self">元素5</div>
      </div>
    </div>
  );

  const itemColumns: TableProps<DataType>["columns"] = [
    {
      title: "api",
      dataIndex: "api",
      key: "api",
    },
    {
      title: "属性",
      dataIndex: "property",
      key: "property",
      render: (value: string) => {
        switch (value) {
          case "order":
            return orderEle;
          case "flex-grow":
            return flexGrowEle;
          case "flex-shrink":
            return flexShrinkEle;
          case "flex-basis":
            return flexBasisEle;
          case "flex":
            return flexEle;
          case "align-self":
            return alignSelfEle;
          default:
            break;
        }
      },
    },
    {
      title: "描述",
      dataIndex: "description",
      key: "description",
      render: (value: string) => {
        return <div dangerouslySetInnerHTML={{ __html: value }} />;
      },
    },
  ];
  const itemData: DataType[] = [
    {
      key: nanoid(),
      api: "项目属性",
    },
    {
      key: nanoid(),
      api: "order",
      property: "order",
      description:
        "order属性定义项目的排列顺序。数值越小，排列越靠前，默认为0。",
    },
    {
      key: nanoid(),
      api: "flex-grow",
      property: "flex-grow",
      description:
        "flex-grow属性定义项目的放大比例，默认为0，即如果存在剩余空间，也不放大。<br>如果所有项目的flex-grow属性都为1，则它们将等分剩余空间（如果有的话）。<br>如果一个项目的flex-grow属性为2，其他项目都为1，则前者占据的剩余空间将比其他项多一倍。",
    },
    {
      key: nanoid(),
      api: "flex-shrink",
      property: "flex-shrink",
      description:
        "flex-shrink属性定义了项目的缩小比例，默认为1，即如果空间不足，该项目将缩小。<br>如果所有项目的flex-shrink属性都为1，当空间不足时，都将等比例缩小。<br>如果一个项目的flex-shrink属性为0，其他项目都为1，则空间不足时，前者不缩小。<br>负值对该属性无效。",
    },
    {
      key: nanoid(),
      api: "flex-basis",
      property: "flex-basis",
      description:
        "flex-basis属性定义了在分配多余空间之前，项目占据的主轴空间（main size）。<br>浏览器根据这个属性，计算主轴是否有多余空间。<br>它的默认值为auto，即项目的本来大小。<br>它可以设为跟width或height属性一样的值（比如350px），则项目将占据固定空间。",
    },
    {
      key: nanoid(),
      api: "flex",
      property: "flex",
      description:
        "flex属性是flex-grow, flex-shrink 和 flex-basis的简写，默认值为0 1 auto。后两个属性可选。<br>该属性有两个快捷值：auto (1 1 auto) 和 none (0 0 auto)。<br>建议优先使用这个属性，而不是单独写三个分离的属性，因为浏览器会推算相关值。",
    },
    {
      key: nanoid(),
      api: "align-self",
      property: "align-self",
      description:
        "align-self属性允许单个项目有与其他项目不一样的对齐方式，可覆盖align-items属性。<br>默认值为auto，表示继承父元素的align-items属性，如果没有父元素，则等同于stretch。<br>该属性可能取6个值，除了auto，其他都与align-items属性完全一致。",
    },
  ];
  return (
    <>
      <div className="w-[294px] text-[#fff] bg-black">
        <div className="flex gap-2 pb-3 pl-3 pr-3 pt-2 flex-wrap">
          {["属性允", "属性", "属性允许单个项", "属性允许单个项"].map(
            (item, index) => (
              <div
                className={`bg-[--color-bg-8] rounded px-4 py-[5px]`}
                key={index}
              >
                {item}
              </div>
            )
          )}
        </div>
      </div>
      <Table
        columns={type === "container" ? columns : itemColumns}
        dataSource={type === "container" ? data : itemData}
      />
    </>
  );
};
